#/!/usr/bin/python
import pygame
from data.MapConst  import *
from game_engine.level_manager import Map as Map
import time
import pickle
import sys
import os
from game_engine.resource_manager import ResourceManager as ResourceManager


class logger:

    def info(self,txt):
        print "[INFO] %s" % (txt)

    def error(self,txt):
        print "[ERROR] %s" % (txt)



class LevelEditor:

    def __init__(self):
        self.m_windowSize = (1024,768)

        self.m_guiHeight = 150
        self.m_guiWidth = self.m_windowSize[1]
        self.m_guiSize = (1024,self.m_guiHeight)
        self.m_guiLocation =  (0,1024-400)
        self.m_guiRect = pygame.Rect(self.m_guiSize,self.m_guiLocation)
        self.m_mapSurface = None
        self.m_uiSurface = None
        self.m_spriteFiles = {}
        self.m_smallTileSize = 15 
        self.m_TileSize = 30
        self.m_filledTiles = {} 
        self.m_mapXMax = None
        self.m_mapYMax = None
        self.m_map = Map.Map()
        self.m_selectedTile = None
        self.m_selectedTileName = None
        self.m_mapFileName = "tmpLevel"
        self.m_resourceManager = ResourceManager.ResourceManager()
        self.m_resourceManager.addResourcePath("images/")

    def setLogger(self,logger):
        self.logger = logger


    def loadMap(self,mapFile):
        self.m_mapFileName = mapFile
        if(os.path.exists(self.m_mapFileName)):
            fd = open("%s" % mapFile,"rb")
            mapSerialObj = fd.read()
            self.m_map = pickle.loads(mapSerialObj)
            print "Loading Map %s [%dx%d]" % (self.m_mapFileName,self.m_map.m_MaxX , self.m_map.m_MaxY)

            fd.close()



    def initialize(self):
        self.setupMapSurface()
        self.setupUISurface()

        #Lets load our map tile file
        self.loadTiles()



    def loadTiles(self):
        for tile in tileMap.values():
            # Read tile definitions and load images
            # Fixup size
            if not("SIZE" in tile):
                tile["SIZE"]=(1,1)
            # Load the file specified as the source of the tile
            img = self.m_resourceManager.loadImage(tile["FILE"])
            # Specify coords for copying out
            tmpRect = pygame.Rect(tile["CORDS"],tile["DEMENSIONS"])
            # Copy out
            tile["SURFACE"].blit(img, (0,0), tmpRect)
            # Size to our tile size
            tile["SURFACE"] = pygame.transform.smoothscale(tile["SURFACE"],(self.m_TileSize, self.m_TileSize))

    
    def setupMapSurface(self):
        self.m_mapSurface = pygame.Surface(self.m_windowSize)
        self.m_mapSurface.fill((0,0,0))



    def setupUISurface(self):
        self.m_uiSurface = pygame.Surface(self.m_guiSize)
        self.m_uiSurface.fill((255,255,255))


    def handleUIClick(self,pos):
        for tile in tileMap.values():
            if(tile["LOCATION"].collidepoint(pos)):
                self.m_selectedTile = tile
                

        

    def handleMapClick(self,pos):
        
        if(self.m_selectedTile == None):
            return

        
        #Lets find our tile
        X = pos[0] - (pos[0] %  self.m_smallTileSize)
        Y = pos[1] - (pos[1] %  self.m_smallTileSize)

        tileX = X / self.m_smallTileSize 
        tileY = Y / self.m_smallTileSize

        self.m_filledTiles[(X,Y)] = self.m_selectedTile

    
    
        self.m_map.addTile((tileX,tileY),self.getTileCharacter(self.m_selectedTile))

        print "%d > %d" % (tileX,self.m_map.m_MaxX)
        if(tileX > self.m_map.m_MaxX):
            print "Adding Max X: ",tileX
            self.m_map.setMaxX(tileX)
        
        if(tileY > self.m_map.m_MaxY):
            print "Adding Max Y: ",tileY
            self.m_map.setMaxY(tileY)
            
        
        return

    def handleRightClick(self,pos):
        #Lets find our tile
        X = pos[0] - (pos[0] %  self.m_smallTileSize)
        Y = pos[1] - (pos[1] %  self.m_smallTileSize)

        tileX = X / self.m_smallTileSize 
        tileY = Y / self.m_smallTileSize
        self.m_map.removeTile((tileX,tileY))

    def handleClick(self,pos):
        if(self.isOverUI(pos)):
            self.handleUIClick(pos)

        else:
            self.handleMapClick(pos)

    def isOverUI(self,pos):
        print self.m_guiLocation[1]
        if(pos[1] > self.m_guiLocation[1]):
            return True
        return False    

    def getTileCharacter(self,tile):
            for char in tileMap.keys():
                if((tileMap[char]["CORDS"] == tile["CORDS"]) and (tileMap[char]["FILE"] == tile["FILE"])):
                    return char
            return None    
                

    def drawMap(self,surface):
        #Lets draw out grid
        
        maxTileX = self.m_mapSurface.get_size()[0] / self.m_smallTileSize
        maxTileY = self.m_mapSurface.get_size()[1] / self.m_smallTileSize
        i=0

        #Draw our X
        for i in range(0,self.m_mapSurface.get_size()[0],self.m_smallTileSize):
            pygame.draw.line(self.m_mapSurface,(255,255,255),(i,1),(i,self.m_mapSurface.get_width()))

        #Draw our Y
        for i in range(0,self.m_mapSurface.get_size()[1],self.m_smallTileSize):
            pygame.draw.line(self.m_mapSurface,(255,255,255),(1,i),(self.m_mapSurface.get_width(),i))


        #Draw our filled tiles  - pass 1, anything 1x1
        for pos in self.m_map.getTiles():
            tile = tileMap[self.m_map.getTiles()[pos]]
            if tile["SIZE"][0] != 1 or tile["SIZE"][1] != 1:
                continue
            x = pos[0] * self.m_smallTileSize
            y = pos[1] * self.m_smallTileSize
            smallSurface = pygame.Surface((self.m_smallTileSize,self.m_smallTileSize))
            smallSurface = pygame.transform.smoothscale(tile["SURFACE"],(self.m_smallTileSize * tile["SIZE"][0], self.m_smallTileSize * tile["SIZE"][1]))
            self.m_mapSurface.blit(smallSurface,(x,y))
        #Draw our filled tiles  - pass 2, anything bigger than 1x1
        for pos in self.m_map.getTiles():
            tile = tileMap[self.m_map.getTiles()[pos]]
            if tile["SIZE"][0] == 1 and tile["SIZE"][1] == 1:
                continue
            x = pos[0] * self.m_smallTileSize
            y = pos[1] * self.m_smallTileSize
            smallSurface = pygame.Surface((self.m_smallTileSize,self.m_smallTileSize))
            smallSurface = pygame.transform.smoothscale(tile["SURFACE"],(self.m_smallTileSize * tile["SIZE"][0], self.m_smallTileSize * tile["SIZE"][1]))
            self.m_mapSurface.blit(smallSurface,(x,y))



        #Draw our editor surface
        surface.blit(self.m_mapSurface,(0,0))

    def drawUI(self,surface):
        #Lets draw our tiles as buttons
        offsetX = 1
        offsetY = 10
        spacing = self.m_TileSize+5

        for tile in tileMap.values():
            self.m_uiSurface.blit(tile["SURFACE"],(offsetX,offsetY))
            tile["LOCATION"] = pygame.Rect((self.m_guiLocation[0] + offsetX , self.m_guiLocation[1] + offsetY),(spacing,spacing))
            offsetX += spacing
            if (offsetX > (1024-spacing)):
                offsetX = 1
                offsetY += spacing


        #Draw our buttons

        surface.blit(self.m_uiSurface,self.m_guiLocation)


    def saveMap(self):
                


        print "Saving Map %s [%dx%d]" % (self.m_mapFileName,self.m_map.m_MaxX , self.m_map.m_MaxY)

        fd = open(self.m_mapFileName ,"wb")
        mapObj = pickle.dumps(self.m_map)
        fd.write(mapObj)
        fd.close()
        
        return
        
        
    def draw(self,surface):

        #Our render order
        self.drawMap(surface)    

        self.drawUI(surface)
    



if __name__ == "__main__":


    log = logger()    
    log.info("Loading")
  
    if(len(sys.argv) < 2):
        print "Must supply map name IE: python LevelEditor.py Level1"
        sys.exit(1)


    mapName = sys.argv[1]
    fileName = "maps/%s.goat" % (mapName)

    pygame.init()
    screen = pygame.display.set_mode((1024,768),0,32)
   
    lvlEditor = LevelEditor()
    lvlEditor.setLogger(log)
    lvlEditor.initialize()
    lvlEditor.loadMap(fileName)


    lvlEditor.draw(pygame.display.get_surface())
    pygame.display.update()
    clock = pygame.time.Clock()



    while(True):
        try:
            clock.tick(40)

            event = pygame.event.poll()
            if event.type == pygame.QUIT:
                 running = 0

            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                print "You pressed the left mouse button at (%d, %d)" % event.pos
                print lvlEditor.handleClick(event.pos)
            elif event.type == pygame.MOUSEBUTTONUP and event.button == 1:
                print "You released the left mouse button at (%d, %d)" % event.pos
            elif event.type == pygame.MOUSEBUTTONUP and event.button == 3:
                lvlEditor.handleRightClick(event.pos)

            elif event.type == pygame.KEYDOWN and event.key == pygame.K_s:
                lvlEditor.saveMap()
                
            lvlEditor.draw(pygame.display.get_surface())
            pygame.display.flip()

        except KeyboardInterrupt:
            print "Done.."
            break



